/**
 * 拖拽管理的入口
 * 调用具体的处理函数来处理拖拽。
 */
import { nextTick } from 'vue'
// UI库的提示
import { ElMessageBox, ElMessage } from 'element-plus'

// 加载 设置 dom 拖拽事件的函数
import setDrag from './set-drag.js'
// 加载 设置 dom 顺序 的函数
import setOrder from './set-order'

/**
 * 列表的拖拽管理
 * @param {*} el 列表、表单、查询
 * @param {*} dragInfo 拖拽中产生的信息
 * @param {*} meta 控件的meta，拖拽后，修改其内容
 * @returns 无
 */
const gridManage = (el, meta) => {
  const msgBox = {
    confirmButtonText: '移除', // + dataListState.choice.dataId,
    cancelButtonText: '不要呀',
    type: 'warning'
  }
  const msgSucess = {
    type: 'success',
    message: '移除成功！'
  }
  const msgError = {
    type: 'info',
    message: '已经取消了。'
  }

  /**
   * 移除选择的字段
   * @param {*} meta 元数据
   * @param {*} dragInfo 拖拽信息
   */
  const _setRemove = (meta, dragInfo) => {
    const col = meta.itemMeta[dragInfo.sourceId]
    ElMessageBox.confirm(`此操作将移除该列：(${col.label}), 是否继续？`, '温馨提示', msgBox)
      .then(() => {
        // 移除
        meta.colOrder.splice(dragInfo.sourceIndex, 1)
        ElMessage(msgSucess)
        nextTick(() => {
          girdSetup() // 重新绘制
        })
      })
      .catch(() => {
        ElMessage(msgError)
      })
  }

  /**
   * 设置th的对齐方式
   */
  const _setThAlgin = (meta, dragInfo) => {
    // 判断 th 还是 td
    const alignKind = (dragInfo.ctrl) ? 'header-align' : 'align'
    const col = meta.itemMeta[dragInfo.sourceId]
    // 判断：左中右
    switch (col[alignKind]) {
      case 'left':
        if (dragInfo.isLeft) {
          col[alignKind] = 'left'
        } else {
          col[alignKind] = 'center'
        }
        break
      case 'center':
        if (dragInfo.isLeft) {
          col[alignKind] = 'left'
        } else {
          col[alignKind] = 'right'
        }
        break
      case 'right':
        if (dragInfo.isLeft) {
          col[alignKind] = 'center'
        } else {
          col[alignKind] = 'right'
        }
        break
    }
  }

  // 定义拖拽的事件
  const dragEvent = {
    outEnd: (dragInfo) => { // 移出结束事件，还是要询问一下
      _setRemove(meta, dragInfo) // 移除
    },
    alignEnd: (dragInfo) => { // 对齐结束事件
      _setThAlgin(meta, dragInfo)
    },
    dragEnd: (dragInfo) => { // 拖拽结束事件
      setOrder(meta, dragInfo) // 调整顺序、交换位置
      nextTick(() => {
        girdSetup() // 重新绘制
      })
    }
  }

  /**
   * 列表的初始化设置
   */
  const girdSetup = () => {
    // 找到 可以拖拽的 dom，这里是 table 的 tr[0] 的 th 集合
    const className = 'el-table__header'
    const table = el.getElementsByClassName(className)[0]
    const tr = table.rows[0] // 表头
    const tdCount = tr.cells.length
    // 记录 th 对应 的字段ID
    const thToColumnId = {}

    // 拖拽信息
    const dragInfo = {
      timeout: null, // 设置拖拽出去的 setTimeout
      state: '', // 拖拽状态，拖拽中（pending），拖拽结束（end）
      offsetX: 0,
      isLeft: true, // 是否在 th 的左侧结束拖拽，左侧或者右侧。
      ctrl: false, // 是否按下了ctrl
      sourceId: '', // 开始拖拽的th对应的字段ID
      targetId: '', // 结束拖拽的th对应的字段ID
      sourceIndex: 0, // 开始拖拽的位置
      targetIndex: 0 // 结束拖拽的位置
    }
    // 设置th的拖拽，第一列是复选框，不算
    for (let i = 1; i < tdCount; i++) {
      const th = tr.cells[i]
      // label 和 字段ID做对应，便于拖拽的时候找到字段ID
      thToColumnId[th.innerText] = meta.colOrder[i - 1]
      // 给 th 设置拖拽事件
      //   拖拽对象 对应的字段ID 拖拽信息 元数据
      setDrag(th, thToColumnId, dragInfo, dragEvent, meta, el)
    }
    document.ondrop = (event) => {
      console.log('el 的 拖拽释放：', event)
    }
  }

  return {
    girdSetup // 列表设置拖拽
  }
}

export default gridManage
